package com.ciwong.mobilelib.utils.AsyncHttp;

import com.android.volley.Request;
import com.ciwong.libs.utils.volley.BaseRequest;
import com.ciwong.libs.utils.volley.HttpHelper;
import com.google.gson.Gson;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.apache.http.Header;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;

/**
 * Created by young on 2017/2/16.
 * 上传文件基础请求类
 */
public class AsynHttpBaseRequest {
    static final String TAG = "asynhttp";

    private final int NEWWORK_ERROR = -105;
    /**
     * 响应数据字段：ret
     */
    public static final String RESPONSE_DATA_COLUMN_RET = "ret";
    /**
     * 响应数据字段：errcode
     */
    public static final String RESPONSE_DATA_COLUMN_ERRCODE = "errcode";

    /**
     * 响应数据字段：msg
     */
    public static final String RESPONSE_DATA_COLUMN_MSG = "msg";

    /**
     * 响应数据字段：data
     */
    public static final String RESPONSE_DATA_COLUMN_DATA = "data";

    AsyncHttpClient asyncHttpClient;

    public AsynHttpBaseRequest() {
        asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.setTimeout(3 * 60 * 1000);
        asyncHttpClient.setMaxConnections(20);
    }

    public void request(int method, String url, RequestParams params, final ResponseCallback callback, final Class<?> responseClazz, final Type responseType) {
        //验证头
        url = buildUrl(true, url);
        if (method == Request.Method.POST) {
            asyncHttpClient.post(url, params, new JsonHttpResponseHandler() {
                        @Override
                        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                            if (null == response) {
                                return;
                            }

                            try {

                                int ret = response.getInt(RESPONSE_DATA_COLUMN_RET);
                                Object object = null;
                                if (ret == 0) {
                                    if (response.has(RESPONSE_DATA_COLUMN_DATA)) {
                                        Gson mGson = new Gson();
                                        if (responseClazz != null) {
                                            object = mGson
                                                    .fromJson(
                                                            response.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseClazz);
                                        } else if (responseType != null) {
                                            object = mGson.fromJson(response.getString(RESPONSE_DATA_COLUMN_DATA), responseType);
                                        }

                                    }
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (response.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = response
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .success(
                                                        object,
                                                        ret,
                                                        errorCode,
                                                        response.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                } else {
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (response.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = response
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .error(errorCode,
                                                        response.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }


                        }


                        @Override
                        public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {

                            try {
                                if (null == errorResponse) {
                                    callback.error(NEWWORK_ERROR, "网络异常statusCode=" + statusCode);
                                    return;
                                }

                                int ret = errorResponse.getInt(RESPONSE_DATA_COLUMN_RET);
                                Object object = null;
                                if (ret == 0) {
                                    if (errorResponse.has(RESPONSE_DATA_COLUMN_DATA)) {
                                        Gson mGson = new Gson();
                                        if (responseClazz != null) {
                                            object = mGson
                                                    .fromJson(
                                                            errorResponse.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseClazz);
                                        } else if (responseType != null) {
                                            object = mGson
                                                    .fromJson(
                                                            errorResponse.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseType);
                                        }
                                    }
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (errorResponse.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = errorResponse
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .success(
                                                        object,
                                                        ret,
                                                        errorCode,
                                                        errorResponse.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                } else {
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (errorResponse.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = errorResponse
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .error(errorCode,
                                                        errorResponse.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                        }
                    }

            );

        } else if (method == Request.Method.GET) {
            asyncHttpClient.get(url, params, new JsonHttpResponseHandler() {
                        @Override
                        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                            if (null == response) {
                                return;
                            }
                            try {
                                int ret = response.getInt(RESPONSE_DATA_COLUMN_RET);
                                Object object = null;
                                if (ret == 0) {
                                    if (response.has(RESPONSE_DATA_COLUMN_DATA)) {
                                        Gson mGson = new Gson();
                                        if (responseClazz != null) {
                                            object = mGson
                                                    .fromJson(
                                                            response.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseClazz);
                                        } else if (responseType != null) {
                                            object = mGson
                                                    .fromJson(
                                                            response.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseType);
                                        }
                                    }
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (response.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = response
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .success(
                                                        object,
                                                        ret,
                                                        errorCode,
                                                        response.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                } else {
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (response.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = response
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .error(errorCode,
                                                        response.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }


                        @Override
                        public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {

                            try {

                                int ret = errorResponse.getInt(RESPONSE_DATA_COLUMN_RET);
                                Object object = null;
                                if (ret == 0) {
                                    if (errorResponse.has(RESPONSE_DATA_COLUMN_DATA)) {
                                        Gson mGson = new Gson();
                                        if (responseClazz != null) {
                                            object = mGson
                                                    .fromJson(
                                                            errorResponse.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseClazz);
                                        } else if (responseType != null) {
                                            object = mGson
                                                    .fromJson(
                                                            errorResponse.getString(RESPONSE_DATA_COLUMN_DATA),
                                                            responseType);
                                        }
                                    }
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (errorResponse.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = errorResponse
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .success(
                                                        object,
                                                        ret,
                                                        errorCode,
                                                        errorResponse.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                } else {
                                    if (callback != null) {
                                        int errorCode = 0;
                                        if (errorResponse.has(RESPONSE_DATA_COLUMN_ERRCODE)) {
                                            errorCode = errorResponse
                                                    .getInt(RESPONSE_DATA_COLUMN_ERRCODE);
                                        }
                                        callback
                                                .error(errorCode,
                                                        errorResponse.getString(RESPONSE_DATA_COLUMN_MSG));
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }

                    }
            );


        } else {
            //请求方式不正确


        }


    }


    /**
     * 请求地址初始化
     *
     * @param isVerifyAction 是否添加Verify动作
     * @return 返回请求地址
     */
    public String buildUrl(boolean isVerifyAction, String url) {
        if (url != null) {
            if (isVerifyAction) {
                if (BaseRequest.getVerifyInfo() == null) {
                    if (!url.endsWith("?") && !url.contains("?")) {
                        //url += "?";
                    }
                } else {
                    url += HttpHelper.getVerifyStr(BaseRequest
                            .getVerifyInfo());
                }
            } else {
                if (!url.endsWith("?") && !url.contains("?")) {
                    //url += "?";
                }
            }
        }


        return url;
    }


    /**
     * 网络请求回调接口
     */
    public abstract static class ResponseCallback {
        /**
         * 网络请求响应成功
         *
         * @param responseStr 响应字符串数据
         */
        public void success(String responseStr) {

        }

        /**
         * 网络请求响应成功
         *
         * @param obj
         * @param resultCode 返回状态码
         * @param errorCode  错误码
         * @param msg        返回状态信息
         */
        public void success(Object obj, int resultCode, int errorCode,
                            String msg) {

        }

        /**
         * 网络请求响应成功<br/>
         * 传入调用者指定的xml sax Handler
         *
         * @param xmlHandler {@link
         */
        public void success(BaseRequest.XmlHandler xmlHandler) {

        }

        /**
         * 网络请求响应错误
         *
         * @param errorCode 错误码
         * @param msg       返回状态信息
         */
        public void error(int errorCode, String msg) {

        }
    }
}
